-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix autosend scheduling #6121
Fix autosend scheduling #6121
Conversation
@WKobus could you take another look at this when you get a chance? The biggest change since you last looked is that "cellular only" shouldn't run when connected to a metered wifi (like a hotspot), but should run eventually if you then just connect to cellular (although it might take a few minutes). |
@@ -81,7 +81,8 @@ interface Scheduler { | |||
|
|||
enum class NetworkType { | |||
WIFI, | |||
CELLULAR | |||
CELLULAR, | |||
OTHER |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OTHER
would just be any other connected network. Android devices can theoretically have network delivered via Ethernet or Bluetooth for example. These kinds of connections would still satisfy WorkManager's (and our won) "connected" constraint.
* Returns class that can be used to schedule this task using Android's | ||
* WorkManager framework | ||
*/ | ||
fun getWorkManagerAdapter(): Class<out WorkerAdapter> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realised we didn't need all this and could just use strings (and no arg constructors) to integrate with WorkManager. It will eventually have to store our class names as strings anyway.
import android.net.ConnectivityManager | ||
import org.odk.collect.async.Scheduler | ||
|
||
class ConnectivityProvider(private val context: Context) : NetworkStateProvider { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to replace this implementation at some point, as it's pretty much all deprecated.
@@ -216,6 +214,14 @@ class InstancesDataService( | |||
} | |||
} | |||
|
|||
fun instanceFinalized(projectId: String, form: Form) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'd ideally have a method that's more like:
fun finalizeInstance(projectId: String, instance: Instance)
But the code that finalises a form during form entry and finalises during bulk finalisation is very different at the moment (the former happens pre save to disk), so that's something for another day.
This one would be really great to get in the next beta if possible. @seadowg did you want @getodk/testers to take another look before review or can @grzesiek2010 take a look? |
@lognaturel Yup! Thanks for the nudge. @WKobus are you able to take another look? |
..._app/src/androidTest/java/org/odk/collect/android/feature/instancemanagement/AutoSendTest.kt
Outdated
Show resolved
Hide resolved
async/src/main/java/org/odk/collect/async/network/NetworkStateProvider.kt
Show resolved
Hide resolved
...src/main/java/org/odk/collect/android/instancemanagement/autosend/InstanceAutoSendFetcher.kt
Show resolved
Hide resolved
...test/java/org/odk/collect/android/backgroundwork/FormUpdateAndInstanceSubmitSchedulerTest.kt
Outdated
Show resolved
Hide resolved
...src/main/java/org/odk/collect/android/instancemanagement/autosend/InstanceAutoSendFetcher.kt
Show resolved
Hide resolved
} | ||
|
||
HashMap<String, String> inputData = new HashMap<>(); | ||
inputData.put(TaskData.DATA_PROJECT_ID, projectId); | ||
scheduler.networkDeferred(getAutoSendTag(projectId), new AutoSendTaskSpec(), inputData, networkType); | ||
scheduler.networkDeferred(getAutoSendTag(projectId), new SendFormsTaskSpec(), inputData, networkConstraint); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need to create objects here like new SendFormsTaskSpec()
. those objects are never used and we just need the class name to create an object based on it later. That means you can pass class names directly here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially, I'd need to experiment with TaskSpecWorker
using a Kotlin object instead of a class (the way the reflection would work would be different if there's no constructor). Let's look at that when we're next playing with async stuff?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
async/src/test/java/org/odk/collect/async/TaskSpecWorkerTest.kt
Outdated
Show resolved
Hide resolved
..._app/src/androidTest/java/org/odk/collect/android/feature/instancemanagement/AutoSendTest.kt
Show resolved
Hide resolved
I was already finishing my review. |
8f8ef48
to
78a1bda
Compare
Tested with Success! Verified on a device with Android 10 Verified Cases:
|
Tested with Success! Verified on a device with Android 14 |
Closes #6120
This also:
It's probably a good idea to wait on merging this until it's marked "behaviour verified" as we've seen a lot of churn on auto send recently.
Why is this the best possible solution? Were any other approaches considered?
I would have loved to have a more elegant solution for "cellular only", but couldn't find one that would work within the WorkManager world. I think the compromise of having other settings work optimally within Android's current background job setup is correct though.
How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
This should mean that auto send now behaves more like how we'd "expect". One caveat to highlight is that metered wifi (like a hotspot) will not work with "wifi only" or "cellular only". The work around for this (other than using "wifi or cellular") is to change the wifi to "unmetered" in Android's settings.
Before submitting this PR, please make sure you have:
./gradlew connectedAndroidTest
(or./gradlew testLab
) and confirmed all checks still pass